<template>
	<a-modal
		class="basic-modal"
		:visible="visible"
		:title="title"
		:width="width"
		:title-align="titleAlign"
		:hide-cancel="hideCancel"
		:mask-closable="maskClosable"
		:footer="footer"
		:mask="mask"
		@update:model-value="emit('update:visible', $event)"
		@open="emit('open')"
		@close="handleClose"
		@cancel="handleCancel"
	>
		<slot></slot>
		<template v-if="footer" #footer>
			<div class="footer">
				<slot name="footer" :confirm="handleConfirm" :confirm-text="okText" :cancel="handleCancel" :cancel-text="cancelText">
					<a-button v-if="!hideCancel" shape="round" size="large" @click="handleCancel">
						{{ cancelText }}
					</a-button>
					<a-button
						:disabled="disabledConfirm"
						:loading="loading"
						size="large"
						shape="round"
						:type="btnType"
						@click="handleConfirm"
					>
						{{ okText }}
					</a-button>
				</slot>
			</div>
		</template>
	</a-modal>
</template>

<script setup lang="ts">
interface IEmit {
	(event: "update:visible", value: boolean): void;
	(event: "ok"): void;
	(event: "cancel"): void;
	(event: "open"): void;
	(event: "close"): void;
}

interface IProps {
	title?: string;
	hideTitle?: boolean;
	titleAlign?: "start" | "center";
	visible: boolean;
	width?: string;
	maskClosable?: boolean;
	okText?: string;
	cancelText?: string;
	hideCancel?: boolean;
	disabledConfirm?: boolean;
	btnType?: "primary" | "dashed" | "outline" | "text";
	btnStatus?: "normal" | "success" | "warning" | "danger";
	footer?: boolean;
	mask?: boolean;
	ok?: PromiseFn | ((...args: any[]) => void);
	cancel?: PromiseFn | ((...args: any[]) => void);
	"onUpdate:visible"?: (value: boolean) => void;
}

const emit = defineEmits<IEmit>();
const props = withDefaults(defineProps<IProps>(), {
	title: "提示",
	width: "520px",
	hideTitle: false,
	titleAlign: "start",
	maskClosable: false,
	okText: "确定",
	cancelText: "取消",
	hideCancel: false,
	disabledConfirm: false,
	footer: true,
	mask: true,
	btnType: "primary",
	btnStatus: "normal"
});

const loading = ref(false);

function closeDialog() {
	emit("update:visible", false);
}

// 确定
async function handleConfirm() {
	if (!props.ok) {
		closeDialog();
		emit("ok");
		return;
	}
	try {
		loading.value = true;
		await props.ok();
		closeDialog();
		emit("ok");
	} finally {
		loading.value = false;
	}
}

// 取消
function handleCancel() {
	closeDialog();
	emit("cancel");
}

// 处理dialog关闭事件
function handleClose() {
	emit("close");
	emit("cancel");
}
</script>

<style scoped lang="less">
.footer {
	@apply flex gap-x-2;
	.el-button {
		height: 32px;
	}
}
</style>
